#include "graphics/sprite_events.h"
#include "graphics/sprite_events_private.h"

void esdlAddListener(struct EsdlSprite* sprite, EsdlEventType eventType, EsdlEventCallback callback, bool capturing) {
    EsdlListener* listener = malloc(sizeof * listener);
    listener->eventType = eventType;
    listener->callback = callback;
    (capturing) ? addLast(&(sprite->capturingListeners), listener) : addLast(&(sprite->bubblingListeners), listener);
}

void esdlRemoveListener(struct EsdlSprite* sprite, EsdlEventType eventType, EsdlEventCallback callback, bool capturing) {
    EsdlLinkedList listeners = NULL;
    (capturing) ? (listeners = sprite->capturingListeners) : (listeners = sprite->bubblingListeners);
    while (listeners != NULL) {
        EsdlListener* l = (EsdlListener*) listeners->data;
        if (l->eventType == eventType && l->callback == callback) {
            (capturing) ? (removeElement(&(sprite->capturingListeners), l)) : (removeElement(&(sprite->bubblingListeners), l));
            free(l);
        }
        listeners = listeners->next;
    }
}

void _setFocus(EsdlEvent* event) {
    //printf("Focus : %d\n", event->sprite->code);
    event->sprite->focus = true;
}

void _removeFocus(EsdlEvent* event) {
    //printf("Blur : %d\n", event->sprite->code);
    event->sprite->focus = false;
}

void esdlAddListenerOnFocus(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_FOCUS, callback, false);
}

void esdlAddListenerOnBlur(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_BLUR, callback, false);
}

void esdlAddListenerOnKeyUp(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_KEY_UP, callback, false);
}

void esdlAddListenerOnKeyDown(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_KEY_DOWN, callback, false);
}

void esdlAddListenerOnMouseUp(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_MOUSE_UP, callback, false);
}

void esdlAddListenerOnMouseDown(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_MOUSE_DOWN, callback, false);
}

void esdlAddListenerOnMouseEnter(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_MOUSE_ENTER, callback, false);
}

void esdlAddListenerOnMouseLeave(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_MOUSE_LEAVE, callback, false);
}

void esdlAddListenerOnMouseMove(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlAddListener(sprite, ON_MOUSE_MOVE, callback, false);
}

void esdlRemoveListenerOnFocus(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_FOCUS, callback, false);
}

void esdlRemoveListenerOnBlur(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_BLUR, callback, false);
}

void esdlRemoveListenerOnKeyUp(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_KEY_UP, callback, false);
}

void esdlRemoveListenerOnKeyDown(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_KEY_DOWN, callback, false);
}

void esdlRemoveListenerOnMouseUp(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_MOUSE_UP, callback, false);
}

void esdlRemoveListenerOnMouseDown(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_MOUSE_DOWN, callback, false);
}

void esdlRemoveListenerOnMouseEnter(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_MOUSE_ENTER, callback, false);
}

void esdlRemoveListenerOnMouseLeave(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_MOUSE_LEAVE, callback, false);
}

void esdlRemoveListenerOnMouseMove(EsdlSprite* sprite, EsdlEventCallback callback) {
    esdlRemoveListener(sprite, ON_MOUSE_MOVE, callback, false);
}
